/**
 * Copyright 厦门中软海晟信息技术有限公司 版权所有 违者必究 2019
 */
package com.opencvjava.lessons.imgproc;

import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static com.opencvjava.support.util.CvUtils.imshow;
import static org.opencv.imgproc.Imgproc.*;
import static org.opencv.imgcodecs.Imgcodecs.*;
import static org.opencv.core.Core.*;

/**
 * @author : sunzb(sunzb@hsit.com.cn)
 * @date: 2019/1/4
 */
@Service
public class L1_BasicDrawing {
    private static final int W = 400;
    private final Logger logger = LoggerFactory.getLogger(L1_BasicDrawing.class);

    public void test() {
        Mat atom_image = Mat.zeros(W, W, CvType.CV_8UC3);
        Mat rook_image = Mat.zeros(W, W, CvType.CV_8UC3);
        MyEllipse(atom_image, 90.0);
        imshow("Drawing 1: Atom", atom_image);
        MyEllipse(atom_image, 0.0);
        imshow("Drawing 1: Atom", atom_image);
        MyEllipse(atom_image, 45.0);
        imshow("Drawing 1: Atom", atom_image);
        MyEllipse(atom_image, -45.0);
        imshow("Drawing 1: Atom", atom_image);
        MyFilledCircle(atom_image, new Point(W / 2, W / 2));
        imshow("Drawing 1 final: Atom", atom_image);
        MyPolygon(rook_image);
        imshow("Drawing 2: Rook", rook_image);
        rectangle(rook_image,
                new Point(0, 7 * W / 8),
                new Point(W, W),
                new Scalar(0, 255, 255),
                -1,
                8,
                0);
        imshow("Drawing 2: Rook", rook_image);
        MyLine(rook_image, new Point(0, 15 * W / 16), new Point(W, 15 * W / 16));
        imshow("Drawing 2: Rook", rook_image);
        MyLine(rook_image, new Point(W / 4, 7 * W / 8), new Point(W / 4, W));
        imshow("Drawing 2: Rook", rook_image);
        MyLine(rook_image, new Point(W / 2, 7 * W / 8), new Point(W / 2, W));
        imshow("Drawing 2: Rook", rook_image);
        MyLine(rook_image, new Point(3 * W / 4, 7 * W / 8), new Point(3 * W / 4, W));
        imshow("Drawing 2: Rook final", rook_image);
    }

    private void MyEllipse(Mat img, double angle) {
        int thickness = 2;
        int lineType = 8;
        int shift = 0;
        ellipse(img,
                new Point(W / 2, W / 2),
                new Size(W / 4, W / 16),
                angle,
                0.0,
                360.0,
                new Scalar(255, 0, 0),
                thickness,
                lineType,
                shift);
    }

    private void MyFilledCircle(Mat img, Point center) {
        int thickness = -1;
        int lineType = 8;
        int shift = 0;
        circle(img,
                center,
                W / 32,
                new Scalar(0, 0, 255),
                thickness,
                lineType,
                shift);
    }

    private void MyPolygon(Mat img) {
        int lineType = 8;
        int shift = 0;
        Point[] rook_points = new Point[20];
        rook_points[0] = new Point(W / 4, 7 * W / 8);
        rook_points[1] = new Point(3 * W / 4, 7 * W / 8);
        rook_points[2] = new Point(3 * W / 4, 13 * W / 16);
        rook_points[3] = new Point(11 * W / 16, 13 * W / 16);
        rook_points[4] = new Point(19 * W / 32, 3 * W / 8);
        rook_points[5] = new Point(3 * W / 4, 3 * W / 8);
        rook_points[6] = new Point(3 * W / 4, W / 8);
        rook_points[7] = new Point(26 * W / 40, W / 8);
        rook_points[8] = new Point(26 * W / 40, W / 4);
        rook_points[9] = new Point(22 * W / 40, W / 4);
        rook_points[10] = new Point(22 * W / 40, W / 8);
        rook_points[11] = new Point(18 * W / 40, W / 8);
        rook_points[12] = new Point(18 * W / 40, W / 4);
        rook_points[13] = new Point(14 * W / 40, W / 4);
        rook_points[14] = new Point(14 * W / 40, W / 8);
        rook_points[15] = new Point(W / 4, W / 8);
        rook_points[16] = new Point(W / 4, 3 * W / 8);
        rook_points[17] = new Point(13 * W / 32, 3 * W / 8);
        rook_points[18] = new Point(5 * W / 16, 13 * W / 16);
        rook_points[19] = new Point(W / 4, 13 * W / 16);
        MatOfPoint matPt = new MatOfPoint();
        matPt.fromArray(rook_points);
        List<MatOfPoint> ppt = new ArrayList<>();
        ppt.add(matPt);
        fillPoly(img,
                ppt,
                new Scalar(255, 255, 255),
                lineType,
                shift,
                new Point(0, 0));
    }

    private void MyLine(Mat img, Point start, Point end) {
        int thickness = 2;
        int lineType = 8;
        int shift = 0;
        line(img,
                start,
                end,
                new Scalar(0, 0, 0),
                thickness,
                lineType,
                shift);
    }
}